package com.starbucks.opencase.service;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.starbucks.opencase.config.configOC;
import com.starbucks.opencase.data.daPath;
import com.starbucks.opencase.enums.enumCMMark;
import com.starbucks.opencase.enums.enumCMKey;
import com.starbucks.opencase.enums.enumCMTip;
import com.starbucks.opencase.enums.enumMatches;
import com.starbucks.opencase.function.funCarry;
import com.starbucks.opencase.function.funCode;
import com.starbucks.opencase.function.funCommand;
import com.starbucks.opencase.function.funSession;
import com.starbucks.opencase.modualr.moPetCarry;
import com.starbucks.opencase.response.resUserLogin;
import com.starbucks.opencase.tool.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class serUserAccount {
    @Autowired
    private funCode funCode;
    @Autowired
    private funCommand funCommand;
    @Autowired
    private funSession funSession;
    @Autowired
    private funCarry funCarry;
    @Autowired
    private configOC configOC;
    @Autowired
    private toolUserAccount toolUserAccount;
    @Autowired
    private toolUserGoods toolUserGoods;
    @Autowired
    private toolUserPet toolUserPet;
    @Autowired
    private toolProperties toolProperties;
    @Autowired
    private toolUserInfo toolUserInfo;
    /**
     * 用户登录
     * @param message
     */
    public void login(String id,JsonNode message){
        long t=System.currentTimeMillis();
        ObjectNode on = new ObjectMapper().createObjectNode();
        on.put(enumCMKey.mark.name(), enumCMMark.login.ordinal());
        on.put(enumCMKey.status.name(), false);
        on.put(enumCMKey.timestamp.name(),t);
        //口令登录
        if(message.has(enumCMKey.command.name())){
            String command=message.get(enumCMKey.command.name()).asText();
            String[] commands=funCommand.decode(command);
            if(commands==null || commands.length!=2){//口令错误
                on.put(enumCMKey.tip.name(), enumCMTip.error_command.getTip());
                funSession.sendMessage(id,on);
                return;
            }
            if(Long.parseLong(commands[1])<t){//口令过期
                on.put(enumCMKey.tip.name(), enumCMTip.past_due_command.getTip());
                funSession.sendMessage(id,on);
                return;
            }
            if(!toolUserAccount.exist("",commands[0])){//号码不对
                on.put(enumCMKey.tip.name(), enumCMTip.error_phone.getTip());
                funSession.sendMessage(id,on);
                return;
            }
            resUserLogin info=toolUserAccount.queryInfo("",commands[0]);
            if(info==null){
                on.put(enumCMKey.tip.name(), enumCMTip.not_has_player.getTip());
                funSession.sendMessage(id,on);
                return;
            }
            if(funSession.isOnlineOfUId(info.getUid()))funSession.close(funSession.getIdOfUId(info.getUid()));
            on.put(enumCMKey.phone.name(), commands[0]);
            on.put(enumCMKey.command.name(), command);
            putLoginInfo(on,info);
            funSession.bindClientUser(id,info.getUid());
            funSession.sendMessage(id,on);
            testBattleEnd(info.getUid());
            return;
        }
        if(!message.has(enumCMKey.phone.name())){
            on.put(enumCMKey.tip.name(), enumCMTip.no_has_phone.getTip());
            funSession.sendMessage(id,on);
            return;
        }
        String phone=message.get(enumCMKey.phone.name()).asText();
        if(phone.length()!=11 || !phone.matches(enumMatches.phone.getStr())){
            on.put(enumCMKey.tip.name(), enumCMTip.error_phone_format.getTip());
            funSession.sendMessage(id,on);
            return;
        }
        on.put(enumCMKey.phone.name(), phone);
        String uid="";
        if(!toolUserAccount.exist(uid,phone)){//账号不存在
            uid=(toolUserAccount.queryAccountNum()+100000)+"";
            toolUserAccount.createNewAccount(uid,phone,toolProperties.queryInfo());
        }else uid=toolUserAccount.queryUId(phone);
        //验证码登录
        if(!message.has(enumCMKey.verification_code.name())){//缺少验证码
            on.put(enumCMKey.tip.name(), enumCMTip.no_has_verification_code.getTip());
            funSession.sendMessage(id,on);
            return;
        }
        String code=message.get(enumCMKey.verification_code.name()).asText();
        if(!funCode.testCode(phone,code)){//验证码错误
            on.put(enumCMKey.tip.name(), enumCMTip.error_verification_code.getTip());
            funSession.sendMessage(id,on);
            return;
        }
        funCode.delete(phone);
        resUserLogin info=toolUserAccount.queryInfo(uid,phone);
        if(funSession.isOnlineOfUId(info.getUid()))funSession.close(funSession.getIdOfUId(info.getUid()));
        putLoginInfo(on,info);
        on.put(enumCMKey.command.name(), funCommand.create(phone));
        funSession.bindClientUser(id,info.getUid());
        funSession.sendMessage(id,on);
        testBattleEnd(info.getUid());
    }
    private void putLoginInfo(ObjectNode on,resUserLogin info){
        on.put(enumCMKey.uid.name(), info.getUid());
        on.put(enumCMKey.avatar.name(), "avatar/"+info.getGender()+".png");
        on.put(enumCMKey.nickname.name(), info.getNickname());
        on.put(enumCMKey.gender.name(), info.getGender());
        on.put(enumCMKey.signature.name(), info.getSignature());
        on.put(enumCMKey.address.name(),info.getAddress());
        on.put(enumCMKey.identity.name(), info.getIdentity());
        on.put(enumCMKey.wx.name(), info.getWx());
        on.put(enumCMKey.energy.name(), info.getEnergy());
        on.put(enumCMKey.status.name(), true);
    }

    /**
     * 用户资料更新
     * @param message
     */
    public void updateUserInfo(String id,JsonNode message){
        ObjectNode on = new ObjectMapper().createObjectNode();
        on.put(enumCMKey.mark.name(), enumCMMark.updateUserInfo.ordinal());
        on.put(enumCMKey.status.name(), false);
        on.put(enumCMKey.timestamp.name(), System.currentTimeMillis());
        if(!funSession.isOnlineOfId(id,on))return;
        String uid= funSession.getUIdOfId(id);
        String phone="";
        if(message.has(enumCMKey.nickname.name()))toolUserAccount.updateNickname(uid,phone,message.get(enumCMKey.nickname.name()).asText());
        if(message.has(enumCMKey.gender.name()))toolUserAccount.updateGender(uid,phone,message.get(enumCMKey.gender.name()).asInt());
        if(message.has(enumCMKey.address.name()))toolUserAccount.updateAddress(uid,phone,message.get(enumCMKey.address.name()).asText());
        if(message.has(enumCMKey.avatar.name()))toolUserAccount.updateAvatar(uid,phone,message.get(enumCMKey.avatar.name()).asText());
        if(message.has(enumCMKey.signature.name()))toolUserAccount.updateSignature(uid,phone,message.get(enumCMKey.signature.name()).asText());
        resUserLogin res=toolUserAccount.queryInfo(uid,phone);
        if(res==null){
            on.put(enumCMKey.tip.name(), enumCMTip.error_handle.getTip());
            funSession.sendMessage(id,on);
            return;
        }
        on.put(enumCMKey.phone.name(), res.getPhone());
        on.put(enumCMKey.uid.name(), res.getUid());
        on.put(enumCMKey.nickname.name(), res.getNickname());
        on.put(enumCMKey.gender.name(), res.getGender());
        on.put(enumCMKey.address.name(), res.getAddress());
        on.put(enumCMKey.avatar.name(), res.getAvatar());
        on.put(enumCMKey.signature.name(), res.getSignature());
        on.put(enumCMKey.status.name(), true);
        on.put(enumCMKey.tip.name(), enumCMTip.success_update_user_info.getTip());
        funSession.sendMessage(id,on);
    }

    /**
     * 发送验证码
     * @param message
     */
    public void sendVerificationCode(String id,JsonNode message) {
        ObjectNode on = new ObjectMapper().createObjectNode();
        on.put(enumCMKey.mark.name(), enumCMMark.sendVerificationCode.ordinal());
        on.put(enumCMKey.status.name(), false);
        on.put(enumCMKey.timestamp.name(), System.currentTimeMillis());
        if (!message.has(enumCMKey.phone.name())) {
            on.put(enumCMKey.tip.name(), enumCMTip.no_has_phone.getTip());
            funSession.sendMessage(id, on);
            return;
        }
        String phone = message.get(enumCMKey.phone.name()).asText();
        on.put(enumCMKey.phone.name(), phone);
        if (phone.length() != 11 || !phone.matches(enumMatches.phone.getStr())) {
            on.put(enumCMKey.tip.name(), enumCMTip.error_phone_format.getTip());
            funSession.sendMessage(id, on);
            return;
        }
        String code= funCode.create(phone);
        if(code==null || code.length()!=6){
            on.put(enumCMKey.tip.name(), enumCMTip.error_verification_code_create.getTip());
            funSession.sendMessage(id, on);
            return;
        }
        on.put(enumCMKey.status.name(),true);
        on.put(enumCMKey.past_due.name(),configOC.getPast_que());
        funSession.sendMessage(id,on);
    }
    public void changeIdentity(String id,JsonNode message){
        ObjectMapper om=new ObjectMapper();
        ObjectNode on=om.createObjectNode();
        on.put(enumCMKey.mark.name(), enumCMMark.changeIdentity.ordinal());
        on.put(enumCMKey.status.name(), false);
        on.put(enumCMKey.timestamp.name(), System.currentTimeMillis());
        if(!funSession.isOnlineOfId(id,on))return;
        String uid=funSession.getUIdOfId(id);
        if(!toolUserInfo.changeIdentity(uid)){
            on.put(enumCMKey.tip.name(), enumCMTip.failed_change_identity.getTip());
            funSession.sendMessage(id,on);
            return;
        }
        on.put(enumCMKey.status.name(), true);
        on.put(enumCMKey.tip.name(), enumCMTip.success_change_identity.getTip());
        on.put(enumCMKey.identity.name(), toolUserInfo.queryIdentity(uid));
        funSession.sendMessage(id,on);
    }
    private void testBattleEnd(String uid){
        List<moPetCarry> as=funCarry.queryEndList(uid);
        Thread.startVirtualThread(new Runnable() {
            @Override
            public void run() {
                ObjectMapper om=new ObjectMapper();
                String id= funSession.getIdOfUId(uid);
                for(moPetCarry mo:as){
                    try{Thread.sleep(3000);}catch (Exception e){}
                    ObjectNode on=om.createObjectNode();
                    on.put(enumCMKey.mark.name(), enumCMMark.battleEnd.ordinal());
                    on.put(enumCMKey.status.name(), true);
                    on.put(enumCMKey.tip.name(), enumCMTip.lose_battle_goods.getTip());
                    on.put(enumCMKey.pid.name(), mo.getPid());
                    on.put(enumCMKey.pname.name(), toolUserPet.queryName(mo.getPid()));
                    on.put(enumCMKey.purl.name(), daPath.getPet(mo.getPid()));
                    on.put(enumCMKey.gid.name(), mo.getGid());
                    on.put(enumCMKey.gname.name(), toolUserGoods.queryName(mo.getGid()));
                    on.put(enumCMKey.gurl.name(), daPath.getGoods(mo.getGid()));
                    on.put(enumCMKey.timestamp.name(), System.currentTimeMillis());
                    funSession.sendMessage(id,on);
                }
            }
        });
    }

    /**
     * 退出登录
     * @param sid
     * @param message
     */
    public void exitLogin(String sid,JsonNode message){
        ObjectMapper om=new ObjectMapper();
        ObjectNode on=om.createObjectNode();
        on.put(enumCMKey.mark.name(), enumCMMark.exitLogin.ordinal());
        on.put(enumCMKey.status.name(), false);
        on.put(enumCMKey.timestamp.name(), System.currentTimeMillis());
        if(!funSession.isOnlineOfId(sid,on))return;
        funSession.unbindClientUser(sid);
        on.put(enumCMKey.status.name(), true);
        funSession.sendMessage(sid,on);
    }
}
